package com.xyht.medicine_management_system.modules.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.medicine_management_system.common.commonReturn.CommonCodeEnum;
import com.xyht.medicine_management_system.common.commonReturn.CommonResult;
import com.xyht.medicine_management_system.common.commonReturn.ResponseResult;
import com.xyht.medicine_management_system.modules.coupon.entity.resp.MmsUserCouponRelationResp;
import com.xyht.medicine_management_system.modules.medicine.entity.MmsMedicine;
import com.xyht.medicine_management_system.modules.medicine.entity.resp.MmsMedicineDetailResp;
import com.xyht.medicine_management_system.modules.medicine.mapper.MmsMedicineMapper;
import com.xyht.medicine_management_system.modules.order.entity.MmsOrderMedicineInfo;
import com.xyht.medicine_management_system.modules.order.mapper.MmsOrderMedicineInfoMapper;
import com.xyht.medicine_management_system.modules.search.entity.MmsSearch;
import com.xyht.medicine_management_system.modules.search.entity.resp.MmsKeywordMedicineResp;
import com.xyht.medicine_management_system.modules.search.entity.resp.MmsSearchKeywordResp;
import com.xyht.medicine_management_system.modules.search.mapper.MmsSearchMapper;
import com.xyht.medicine_management_system.modules.search.service.MmsSearchService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.medicine_management_system.modules.order.constant.OrderMedicineInfoConstant.ORDER_MEDICINE_INFO_ORDER;
import static com.xyht.medicine_management_system.modules.search.constant.pageConstant.PAGE_NUM;
import static com.xyht.medicine_management_system.modules.search.constant.pageConstant.PAGE_SIZE;
import static com.xyht.medicine_management_system.modules.search.constant.searchTypeConstant.*;
import static com.xyht.medicine_management_system.modules.search.constant.upDownConstant.UP_DOWN_DES;
import static com.xyht.medicine_management_system.modules.search.constant.upDownConstant.UP_DOWN_UP;

/**
 * <p>
 * 首页搜索记录表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-02-18
 */
@Service
public class MmsSearchServiceImpl extends ServiceImpl<MmsSearchMapper, MmsSearch> implements MmsSearchService {

    @Resource
    private MmsSearchMapper mmsSearchMapper;
    @Resource
    private MmsMedicineMapper mmsMedicineMapper;
    @Resource
    private MmsOrderMedicineInfoMapper mmsOrderMedicineInfoMapper;

    @Override
    public ResponseResult searchMedicineList(String keyword, Integer searchType, Integer upDown, Integer pageNum, Integer pageSize) {

        if (searchType == SEARCH_TYPE_PRICE || searchType == SEARCH_TYPE_SALE) {
            if (isNullOrEmpty(upDown)) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }
        //关键词记录
        if (!isNullOrEmpty(keyword)) {
            List<MmsSearch> searchList = mmsSearchMapper.selectList(new LambdaQueryWrapper<MmsSearch>()
                    .eq(MmsSearch::getSearchKeyword, keyword));
            //记录关键词
            if (searchList.isEmpty()) {
                MmsSearch addSearch = new MmsSearch();
                addSearch.setSearchKeyword(keyword);
                addSearch.setSearchTimes(1);
                mmsSearchMapper.insert(addSearch);
                //关键词次数+1
            } else {
                MmsSearch updateSearch = searchList.get(0);
                updateSearch.setSearchTimes(updateSearch.getSearchTimes()+1);
                mmsSearchMapper.updateById(updateSearch);
            }

        }



        Page<MmsMedicine> page = new Page<>(pageNum,pageSize);
        List<MmsMedicineDetailResp> medicineDetailList = new ArrayList<>();
        List<MmsMedicineDetailResp> medicineDetailCollectList = new ArrayList<>();
        //输入关键词搜索
        LambdaQueryWrapper<MmsMedicine> medicineLambdaQueryWrapper = new LambdaQueryWrapper<MmsMedicine>();
        if (!isNullOrEmpty(keyword)) {
            medicineLambdaQueryWrapper.and(i -> i.like(MmsMedicine::getFunctionalIndications, keyword)
                    .or()
                    .like(MmsMedicine::getCommonNames, keyword));
        } else {
            return CommonResult.success(medicineDetailList,0);
        }

        mmsMedicineMapper.selectPage(page, medicineLambdaQueryWrapper);
        List<MmsMedicine> records = page.getRecords();
//            keywordMedicineList = page.getRecords()
//                    .stream()
//                    .map(mmsMedicine -> {
//                        MmsKeywordMedicineResp keywordMedicineResp = new MmsKeywordMedicineResp();
//                        keywordMedicineResp.setCommonNames(mmsMedicine.getCommonNames());
//                        keywordMedicineResp.setId(mmsMedicine.getId());
//                        return keywordMedicineResp;
//                    })
//                    .collect(Collectors.toList());
        if (!isNullOrEmpty(searchType)) {
            if (searchType == SEARCH_TYPE_SYNTHESIZE) {
                medicineDetailList = records
                    .stream()
                    .map(mmsMedicine -> {
                        MmsMedicineDetailResp medicineResp = new MmsMedicineDetailResp();
                        BeanUtils.copyProperties(mmsMedicine,medicineResp);
                        return medicineResp;
                    })
                    .collect(Collectors.toList());
                return CommonResult.success(medicineDetailList,(int)page.getTotal());

            } else if (searchType == SEARCH_TYPE_PRICE) {
                if (upDown == UP_DOWN_UP) {
                    medicineLambdaQueryWrapper.orderByAsc(MmsMedicine::getSalesPrice);
                } else if (upDown == UP_DOWN_DES) {
                    medicineLambdaQueryWrapper.orderByDesc(MmsMedicine::getSalesPrice);
                }
                Page<MmsMedicine> pricePage = new Page<>(pageNum,pageSize);
                mmsMedicineMapper.selectPage(pricePage, medicineLambdaQueryWrapper);
                medicineDetailList = pricePage.getRecords()
                        .stream()
                        .map(mmsMedicine -> {
                            MmsMedicineDetailResp medicineResp = new MmsMedicineDetailResp();
                            BeanUtils.copyProperties(mmsMedicine,medicineResp);
                            return medicineResp;
                        })
                        .collect(Collectors.toList());
                return CommonResult.success(medicineDetailList,(int)pricePage.getTotal());
            } else if (searchType == SEARCH_TYPE_SALE) {
                List<MmsMedicine> medicineList = mmsMedicineMapper.selectList(medicineLambdaQueryWrapper);
                List<Map<String, Object>> mapList = mmsOrderMedicineInfoMapper.selectMaps(new QueryWrapper<MmsOrderMedicineInfo>()
                        .select("sum(num) as salesVolume,medicine_code as medicineCode")
                        .lambda()
                        .eq(MmsOrderMedicineInfo::getType, ORDER_MEDICINE_INFO_ORDER)
                        .groupBy(MmsOrderMedicineInfo::getMedicineCode));
                if (!mapList.isEmpty()) {
                    List<MmsMedicineDetailResp> medicineDetailRespList = JSONObject.parseArray(JSON.toJSONString(mapList), MmsMedicineDetailResp.class);
                    medicineDetailList = medicineList.stream()
                            .map(mmsMedicine -> {
                                        MmsMedicineDetailResp medicineResp = new MmsMedicineDetailResp();
                                        BeanUtils.copyProperties(mmsMedicine, medicineResp);
                                        List<MmsMedicineDetailResp> collectList = medicineDetailRespList.stream().filter(i -> i.getMedicineCode().equals(mmsMedicine.getMedicineCode())).collect(Collectors.toList());
                                        if (!collectList.isEmpty()) {
                                            medicineResp.setSalesVolume(collectList.get(0).getSalesVolume());
                                        } else {
                                            medicineResp.setSalesVolume(0);
                                        }

                                        return medicineResp;
                                    })
                            .collect(Collectors.toList());
                } else {
                    medicineDetailList = medicineList.stream()
                            .map(mmsMedicine -> {
                                MmsMedicineDetailResp medicineResp = new MmsMedicineDetailResp();
                                BeanUtils.copyProperties(mmsMedicine, medicineResp);
                                return medicineResp;
                            })
                            .collect(Collectors.toList());
                }


                if (upDown == UP_DOWN_UP) {
                    // 根据销量大小倒序排序
                    medicineDetailList.stream().sorted((o1, o2) -> {
                        Integer sale1 = 0;
                        Integer sale2 = 0;
                        //设置 o1 销量
                        if (o1 != null) {
                            sale1 = o1.getSalesVolume();
                        }
                        //设置 o2 销量
                        if (o2 != null) {
                            sale2 = o2.getSalesVolume();
                        }

                        return sale1.compareTo(sale2); // 升序
                    }).collect(Collectors.toList());
                } else if (upDown == UP_DOWN_DES) {
                    medicineDetailList.stream().sorted(new Comparator<MmsMedicineDetailResp>() { // 根据金额大小倒序排序
                        @Override
                        public int compare(MmsMedicineDetailResp o1, MmsMedicineDetailResp o2) {
                            Integer sale1 = 0;
                            Integer sale2 = 0;
                            //设置 o1 销量
                            if (o1 != null) {
                                sale1 = o1.getSalesVolume();
                            }
                            //设置 o2 销量
                            if (o2 != null) {
                                sale2 = o2.getSalesVolume();
                            }

                            return sale2.compareTo(sale1); // 降序排序
                        }
                    }).collect(Collectors.toList());
                }
                medicineDetailCollectList = medicineDetailList.stream().skip((pageNum-1) * pageSize)
                        .limit(pageSize).collect(Collectors.toList());
            }
        }

        return CommonResult.success(medicineDetailCollectList,medicineDetailList.size());
    }

    @Override
    public ResponseResult searchEnterKeywordList(String keyword,Integer pageNum,Integer pageSize) {
        Page<MmsMedicine> page = new Page<>(pageNum,pageSize);
        List<MmsKeywordMedicineResp> enterKeywordMedicineList = new ArrayList<>();
        //输入关键词
        if (!isNullOrEmpty(keyword)) {
            mmsMedicineMapper.selectPage(page, new LambdaQueryWrapper<MmsMedicine>()
                    .and(i -> i.like(MmsMedicine::getFunctionalIndications, keyword)
                            .or()
                            .like(MmsMedicine::getCommonNames, keyword)));
            enterKeywordMedicineList = page.getRecords()
                    .stream()
                    .map(mmsMedicine -> {
                        MmsKeywordMedicineResp mmsKeywordMedicineResp = new MmsKeywordMedicineResp();
                        mmsKeywordMedicineResp.setCommonNames(mmsMedicine.getCommonNames());
                        mmsKeywordMedicineResp.setId(mmsMedicine.getId());
                        return mmsKeywordMedicineResp;
                    })
                    .collect(Collectors.toList());

        }
        return CommonResult.success(enterKeywordMedicineList,(int)page.getTotal());
    }

    @Override
    public ResponseResult getHotKeywordList() {
        Page<MmsSearch> page = new Page<>(PAGE_NUM,PAGE_SIZE);
        mmsSearchMapper.selectPage(page,new LambdaQueryWrapper<MmsSearch>().orderByDesc(MmsSearch::getSearchTimes));
        List<MmsSearchKeywordResp> keywordList = page.getRecords()
                .stream()
                .map(mmsSearch -> {
                    MmsSearchKeywordResp mmsSearchKeywordResp = new MmsSearchKeywordResp();
                    mmsSearchKeywordResp.setSearchKeyword(mmsSearch.getSearchKeyword());
                    return mmsSearchKeywordResp;
                })
                .collect(Collectors.toList());
        return CommonResult.success(keywordList);
    }
}
